package com.micro.plugins.oss.manager;

import com.micro.plugins.oss.enums.OssRuleFlag;
import com.micro.plugins.oss.executor.OssRuleExecutor;
import com.micro.plugins.oss.vo.UploadFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * <h1>对象存储规则执行管理器</h1>
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/5/8
 */
@Slf4j
@Component("OssExecuteManager")
@SuppressWarnings("all")
public class OssExecuteManager implements BeanPostProcessor {

    /**
     * 定义规则执行器映射
     */
    private Map<OssRuleFlag,OssRuleExecutor> executorIndex = new HashMap<>(OssRuleFlag.values().length);


    /**
     * 云存储规则计算入口
     * @param settlementInfo
     * @return
     * @throws CouponException
     */
    public String computeRule(String ossProvider,UploadFile uploadFile) {
        String resultUrl = null;
        OssRuleFlag ossRuleFlag = OssRuleFlag.of(ossProvider);
        switch (ossRuleFlag){
            case OSS_SERVICE_PROVIDER_QCLOUD:
                resultUrl = executorIndex.get(OssRuleFlag.OSS_SERVICE_PROVIDER_QCLOUD).upload(uploadFile);
                break;
            case OSS_SERVICE_PROVIDER_ALIYUN:
                resultUrl = executorIndex.get(OssRuleFlag.OSS_SERVICE_PROVIDER_ALIYUN).upload(uploadFile);
                break;
            case OSS_SERVICE_PROVIDER_QINIUYUN:
                resultUrl = executorIndex.get(OssRuleFlag.OSS_SERVICE_PROVIDER_QINIUYUN).upload(uploadFile);
                break;
        }
        return resultUrl;
    }


    /**
     * 在bean初始化之前进行执行(before)
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Nullable
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //如果当前bean不是OssRuleExecutor的实现则直接返回bean
        if(!(bean instanceof OssRuleExecutor)){
            return bean;
        }
        //把bean强转为RuleExecutor
        OssRuleExecutor ruleExecutor = (OssRuleExecutor) bean;
        OssRuleFlag ruleFlag = ruleExecutor.ruleConfig();
        //如果ruleFlag已经注册了则抛出异常
        if(executorIndex.containsKey(ruleFlag)){
            throw new IllegalStateException("There is already an executor fro rule flag" + ruleFlag);
        }
        log.info("Load executor {} for rule flag {}",ruleExecutor.getClass(),ruleFlag);
        executorIndex.put(ruleFlag,ruleExecutor);
        return null;
    }

    /**
     * 在bean初始化之后进行执行(after)
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Nullable
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
